import math
from typing import List, Literal, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import not_, select, desc
from sqlalchemy import select, distinct, func, desc
from sqlalchemy.orm import joinedload
from app.models import Activity
from sqlalchemy.ext.asyncio import AsyncSession

from app.models import ActivityCampus
from app.schemas import Api
from app.schemas.basic import Paginated
from app.schemas.activity import ActivityDetail, ActivityFilter, ActivitySuggestions, CampusType


class ActivityService:
    def __init__(self, db: AsyncSession):
        self.db = db
        pass

    # http://localhost:8080/post/activity/suggestions
    async def get_activity_suggestions(self) -> Api[Paginated[ActivitySuggestions]]:
        try:
            # 获取最新的活动作为推荐
            # 构建查询语句
            stmt = (
                select(Activity)
                .order_by(desc(Activity.id))
                .options(joinedload(Activity.publisher_relation))
                .limit(5)
            )
            # 执行查询
            activities = await self.db.execute(stmt)

            result = []
            for activity in activities.scalars():
                try:
                    # 打印调试信息
                    print(f"Processing activity {activity.id}")
                    print(f"Activity campuses value: {activity.campuses}")
                    
                    obj = ActivitySuggestions.model_validate({
                        "id": activity.id,
                        "name": activity.name,
                        "date_time": activity.activity_time,
                        "type_id": activity.type,
                        "poster": activity.poster,
                        "campuses": CampusType(activity.campuses) if activity.campuses is not None else CampusType.WEIJINLU
                    })
                    result.append(obj)
                except Exception as e:
                    print(f"Error processing activity {activity.id}: {str(e)}")
                    print(f"Activity data: {activity.__dict__}")
                    continue

            obj = Paginated[ActivitySuggestions].model_validate({
                "total_page": 1,
                "current_page": 1,
                "has_next": False,
                "data": result,
            })
            obj = Api[Paginated[ActivitySuggestions]].model_validate({
                "code": 10000,
                "data": obj,
            })
            return obj
        except Exception as e:
            print(f"Error in get_activity_suggestions: {str(e)}")
            raise
    
    async def get_activities_filter(
        self, 
        page: int = 1, 
        size: int = 10,
        query: Optional[str] = None, 
        locations: Literal[None, 0, 1] = None, 
        categories: Optional[List[int]] = None, 
        sort_by: Literal[None, 0, 1] = None, 
    ) -> Api[Paginated[ActivityFilter]]:
        # 构建基础查询
        stmt = select(Activity)
        
        if locations is not None:
            # 直接使用数字进行过滤
            stmt = stmt.filter(Activity.campuses == locations)

        if categories:
            stmt = stmt.filter(Activity.type.in_(categories))

        stmt = stmt.options(joinedload(Activity.publisher_relation))

        # 排序
        最新发布 = 0
        最近活动 = 1
        if sort_by == 最近活动:
            stmt = stmt.order_by(desc(Activity.activity_time))
        elif sort_by == 最新发布:
            stmt = stmt.order_by(desc(Activity.activity_time))
        else:  # 默认按 ID 排序
            stmt = stmt.order_by(desc(Activity.id))
        
        # 计算总数和分页
        total_stmt = select(func.count()).select_from(stmt.subquery())
        total = await self.db.execute(total_stmt)
        total_pages = math.ceil(total.scalar_one() / size)

        # 分页查询
        stmt = stmt.offset((page - 1) * size).limit(size)
        activities = await self.db.execute(stmt)

        result = []
        for activity in activities.scalars():
            obj = ActivityFilter.model_validate({
                "id": activity.id,
                "name": activity.name,
                "date_time": activity.activity_time,
                "submission_deadline": activity.submission_deadline,
                "type_id": activity.type,
                "poster": activity.poster,
                "publisher_name": activity.publisher_relation.display_name,
                "publisher_avatar": activity.publisher_relation.avatar
            })
            result.append(obj)
        obj = Paginated[ActivityFilter].model_validate({
            "total_page": total_pages,
            "current_page": page,
            "has_next": page < total_pages,
            "data": result,
        })
        obj = Api[Paginated[ActivityFilter]].model_validate({
            "code": 10000,
            "data": obj,
        })
        return obj
    
    async def get_activity_detail(self, id: int) -> Api[ActivityDetail]:
        # 构建查询语句
        stmt = select(Activity).filter(Activity.id == id).options(
            joinedload(Activity.publisher_relation), 
        )
        # 执行查询
        activity = await self.db.execute(stmt)
        activity = activity.scalar_one_or_none()

        if not activity:
            raise HTTPException(
                status_code=404, detail={"code": 40001, "data": "请求数据不存在"}
            )

        try:
            obj = ActivityDetail.model_validate({
                "id": activity.id,
                "name": activity.name,
                "activity_time": activity.activity_time,
                "additional_conditions": activity.additional_conditions,
                "limit": activity.count_limit,
                "deadline": activity.submission_deadline,
                "location": activity.location,
                "type_id": activity.type,
                "poster": activity.poster,
                "publisher_name": activity.publisher_relation.display_name,
                "publisher_avatar": activity.publisher_relation.avatar,
                "campuses": CampusType(activity.campuses) if activity.campuses is not None else CampusType.WEIJINLU
            })
            obj = Api[ActivityDetail].model_validate({
                "code": 10000,
                "data": obj,
            })
            return obj
        except Exception as e:
            print(f"Error in get_activity_detail: {str(e)}")
            print(f"Activity data: {activity.__dict__}")
            raise
    
    async def get_activity_content(self, id: int) -> Api[str]:
        # 构建查询语句
        stmt = select(Activity).filter(Activity.id == id)
        # 执行查询
        activity = await self.db.execute(stmt)
        activity = activity.scalar_one_or_none()

        # if not activity:
        #     raise HTTPException(
        #         status_code=404, detail={"code": 40001, "data": "请求数据不存在"}
        #     )
        obj = Api[str].model_validate({
            "code": 10000,
            "data": activity.content,
        })
        return obj
    
    async def get_activity_poster(self, id: int) -> Api[str]:
        # 构建查询语句
        stmt = select(Activity).filter(Activity.id == id)
        # 执行查询
        activity = await self.db.execute(stmt)
        activity = activity.scalar_one_or_none()

        # if not activity:
        #     raise HTTPException(
        #         status_code=404, detail={"code": 40001, "data": "请求数据不存在"}
        #     )
        obj = Api[str].model_validate({
            "code": 10000,
            "data": activity.poster,
        })
        return obj